﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Graphics;
using Tron.Players;
using Tron.Animations;

namespace Tron
{
    [Serializable]
    class Board : IBoardStatePercepts
    {
        [NonSerialized]
        Game game;

        [NonSerialized]
        BoardGraphics boardGraphics;

        [NonSerialized]
        List<Color> playerColors;

        int[,] blockArray;
        public int[,] BlockArray
        {
            get
            {
                return blockArray;
            }
        }

        [NonSerialized]
        PlayerManager playerManager;
        public PlayerManager PlayerManager
        {
            get { return playerManager; }
            set { playerManager = value; }
        }

        public int this[Vector2 position]
        {
            get
            {
                return blockArray[(int)position.X, (int)position.Y];
            }
        }

        public Board(Game game, int rows, int columns, List<Color> playerColors)
        {
            this.game = game;

            blockArray = new int[columns, rows];
            for (int x = 0; x < columns; x++)
            {
                for (int y = 0; y < rows; y++)
                {
                    blockArray[x, y] = -2;
                }
            }
            boardGraphics = new BoardGraphics(game, rows, columns);
            this.playerColors = playerColors;
            SetupEdgeBlocks(Color.DarkGray);
            SetupCustomBlocks();
        }

        public override string ToString()
        {
            String s = String.Empty;
            for (int x = 0; x < blockArray.GetLength(0); x++)
            {
                for (int y = 0; y < blockArray.GetLength(1); y++)
                {
                    s += blockArray[x, y];
                }
            }

            return s;            
        }
        public void Draw(GameTime gameTime, SpriteBatch spriteBatch)
        {
            boardGraphics.Draw(gameTime, spriteBatch);
        }

        public void SetBlockValue(int x, int y, int playerIndex, bool alive)
        {
            blockArray[x, y] = playerIndex;
            boardGraphics.BlockGraphicsArray[x, y].Color = playerColors[playerIndex];
            if(alive)
                boardGraphics.BlockGraphicsArray[x, y].Style = BlockGraphics.Styles.Solid;
            else
                boardGraphics.BlockGraphicsArray[x, y].Style = BlockGraphics.Styles.Explosion;
        }

        void SetupNeutralBlock(int x, int y, Color color)
        {
            blockArray[x, y] = -1;
            boardGraphics.BlockGraphicsArray[x, y].Color = color;
            boardGraphics.BlockGraphicsArray[x, y].Style = BlockGraphics.Styles.Solid;
        }

        private void SetupCustomBlocks()
        {
            if(String.IsNullOrEmpty(Constants.WallPattern))
            {
                return;
            }
            else
            {
                Texture2D customWallTexture = game.Content.Load<Texture2D>("Textures\\WallPatterns\\" + Constants.WallPattern);

                int xLength = Math.Min(blockArray.GetLength(0), customWallTexture.Width);
                int yLength = Math.Min(blockArray.GetLength(1), customWallTexture.Height);

                Color[] customWallTextureColors = new Color[xLength * yLength];
                customWallTexture.GetData<Color>(0, new Rectangle(0, 0, xLength, yLength), customWallTextureColors, 0, xLength*yLength);
                for(int x = 0; x < xLength; x++)
                {
                    for(int y = 0; y < yLength; y++)
                    {
                        Color color = customWallTextureColors[x + y * xLength];
                        if (color != Color.White)
                        {
                            SetupNeutralBlock(x, y, color);
                        }
                    }
                }
                //customWalls.Height
            }
        }

        public void SetupEdgeBlocks(Color color)
        {
            int xLength = blockArray.GetLength(0);
            int yLength = blockArray.GetLength(1);

            for (int x = 0; x < xLength; x++)
            {
                SetupNeutralBlock(x, 0, color);
            }
            for (int y = 0; y < yLength; y++)
            {
                SetupNeutralBlock(0, y, color);
            }
            for (int x = 0; x < xLength; x++)
            {
                SetupNeutralBlock(x, yLength - 1, color);
            }
            for (int y = 0; y < yLength; y++)
            {
                SetupNeutralBlock(xLength - 1, y, color);
            }
        }

        public void SetPlayerBlockStuff(List<BlockGraphics> playerBlockGraphics, List<BlockAnimator> playerBlockAnimators)
        {
            boardGraphics.PlayerBlockGraphics = playerBlockGraphics;
            boardGraphics.PlayerBlockAnimators = playerBlockAnimators;
        }
    }
}
